package com.acme.bankapp.domain.bank;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import com.acme.bankapp.domain.account.AbstractAccount;
import com.acme.bankapp.domain.account.Account;
import com.acme.bankapp.domain.client.Client;

/**
 * Class provides methods to get statistics about the bank.
 *
 * @author S.Zhidkov
 */
public class BankReport {

    /**
     * Returns number of the bank clients.
     *
     * @param bank
     * @return number of clients
     */
    public int getNbOfCustomers(Bank bank) {
        return bank.getClients().size();
    }

    /**
     * Returns number of the all accounts from all the clients in the bank.
     *
     * @param bank
     * @return
     */
    public int getNbOfAccounts(Bank bank) {
        int numberOfAccounts = 0;
        Set<Client> clients = bank.getClients();
        for (Client client : clients) {
            numberOfAccounts += client.getAccounts().size();
        }
        return numberOfAccounts;
    }

    /**
     * Returns set of the accounts, sorted by available sum.
     *
     * @param bank
     * @return {@code SortedSet} of accounts
     */
    public SortedSet<Account> getAccountsSortedBySum(Bank bank) {
        SortedSet<Account> sortedAccounts = new TreeSet<Account>(AbstractAccount.COMPARE_BY_SUM);
        Set<Client> clients = bank.getClients();

        for (Client client : clients) {
            sortedAccounts.addAll(client.getAccounts());
        }
        return sortedAccounts;
    }

    /**
     * Returns sum credit from all the clients.
     *
     * @param bank
     * @return
     */
    public double getBankCredit(Bank bank) {
        double sum = 0;
        Set<Client> clients = bank.getClients();
        for (Client client : clients) {
            Set<Account> accounts = client.getAccounts();
            for (Account account : accounts) {
                sum += account.getTakedCredit();
            }
        }
        return sum;
    }

    /**
     * Returns {@code Map<Client, Set<Account>>}
     *
     * @param bank
     * @return map Client => Set<Account>
     */
    public Map<Client, Set<Account>> getCustomerAccount(Bank bank) {
        Map<Client, Set<Account>> map = new HashMap<Client, Set<Account>>();
        Set<Client> clients = bank.getClients();

        for (Client client : clients) {
            map.put(client, client.getAccounts());
        }
        return map;
    }
}
